#include <iostream>
#include "Streambuffer.h"

using namespace std;

Streambuffer::Streambuffer()
{
	for(int i = 0; i < SB_SIZE; i++)
	{
		sb[i] = SB_DEFUALT_VALUE;
		sb_stat[i] = SB_UNDEFINED;
	}

	for(int i = 0; i < SB_SIZE/2; i++)
		sb_f[i] = SB_DEFUALT_VALUE;
		
	for(int i = 0; i < SB_SRF_BUS_SIZE; i++)
	{
		srf_bus[i] = SB_DEFUALT_VALUE;
		srf_bus_stat[i] = SB_UNDEFINED;
	}

	for(int i = 0; i < SB_SRF_BUS_SIZE/2; i++)
		srf_bus_f[i] = SB_DEFUALT_VALUE;

	CyclesLeft = 0;
	Ready = true;
	client = 0;
	client_f = 0;
	control = 0;
	control_loc = 0;
}

void Streambuffer::update()
{
	int index = 0;

	if(Ready)
	{
		if( SB_NOP != control )
		{
			if (control_loc < 0 || control_loc >= SB_SIZE)
				return;

			switch (control)
			{
			case SB_WRITE_BUS:
				CyclesLeft = 1;
				break;
			case SB_READ_BUS:
				CyclesLeft = 1;
				break;
			case SB_WRITE_CLIENT:
				CyclesLeft = 1;
				break;
			case SB_WRITE_FLOAT_CLIENT:
				CyclesLeft = 1;
				break;
			case SB_READ_CLIENT:
				CyclesLeft = 1;
				break;
			case SB_READ_FLOAT_CLIENT:
				CyclesLeft = 1;
				break;
			}

			Ready = false;
			update();
		}
	}
	else // Not ready, processing operation
	{
		CyclesLeft--;

		if( 0 == CyclesLeft )
		{
			switch( control )
			{
				case SB_WRITE_BUS:
					for(int i = 0; i < SB_SRF_BUS_SIZE; i++)
					{
						index = (i+control_loc)%SB_SIZE;
						srf_bus[i] = sb[index];
						index = (i+control_loc)%SB_SIZE;
						srf_bus_stat[i] = sb_stat[index];
					}
					for(int i = 0; i < SB_SRF_BUS_SIZE/2; i++)
					{
						index = (i+(control_loc/2))%(SB_SIZE/2);
						srf_bus_f[i] = sb_f[index];
					}
				case SB_READ_BUS:
						for(int i = 0; i < SB_SRF_BUS_SIZE; i++)
					{
						index = (i+control_loc)%SB_SIZE;
						sb[index] = srf_bus[i];
						index = (i+control_loc)%SB_SIZE;
						sb_stat[index] = srf_bus_stat[i];
					}
					for(int i = 0; i < SB_SRF_BUS_SIZE/2; i++)
					{
						index = (i+(control_loc/2))%(SB_SIZE/2);
						sb_f[index] = srf_bus_f[i];
					}
					break;
				case SB_WRITE_CLIENT:
					client = sb[control_loc];
					break;
				case SB_WRITE_FLOAT_CLIENT:
					client_f = sb_f[control_loc/2];
					break;
				case SB_READ_CLIENT:
					sb[control_loc] = client;
					sb_stat[control_loc] = SB_INT;
					break;
				case SB_READ_FLOAT_CLIENT:
					sb_f[control_loc/2] = client_f;
					sb_stat[control_loc] = SB_FLOAT;
					sb_stat[control_loc] = SB_FLOAT;
					break;
			}

			Ready = true;
		}
	}
}

bool Streambuffer::isReady()
{
	return Ready;
}

